/*
 * COPYRIGHT(c) SK telecom 2009
 * This software is the proprietary information of SK telecom.
 *
 * Revision History
 * Author     Date          Description
 * --------   ----------    ------------------
 * 홍길동            2009. 4. 29.    Description
 *
 */
package com.tistory.admin.adminmgr.auth.service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.ibatis.dao.client.DaoManager;
import com.omp.admin.adminmgr.auth.model.AdminAuthMgr;
import com.omp.admin.adminmgr.auth.model.AdminMember;
import com.omp.commons.paging.PageNavigator;
import com.omp.commons.paging.PageResultList;
import com.omp.commons.persistence.dao.DaoConfig;
import com.tisotry.admin.adminmgr.auth.persistence.dao.AdminMemberDAO;
import com.tistory.admin.common.log.OmpLogger;
import com.tistory.admin.common.util.config.DevProperties;

/**
 * TODO 클래스 설명을 입력해 주세요.
 * <p/>
 * 상세한 설명을 입력해 주세요.
 * 
 * @author 홍길동
 * @version 0.1
 */
public class AdminMemberServiceImpl implements AdminMemberService {
	private AdminMemberDAO adminMemberDao = null;
	DaoManager daoManager = null;

	public AdminMemberServiceImpl() {
		this.daoManager = DaoConfig.getDaoManager();
		this.adminMemberDao = (AdminMemberDAO) this.daoManager.getDao(AdminMemberDAO.class);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.omp.admin.adminmgr.auth.service.AdminMemberService#adminMemberDelete(java.lang.String)
	 */
	@Override
	public int adminMemberDelete(String id) {

		int deleteCnt = 0;
		if (id.indexOf(',') > 0) {
			String[] idArr = id.split(",");
			for (int i = 0; i < idArr.length; i++) {
				deleteCnt += this.adminMemberDao.adminMemberDelete(idArr[i]);
				this.adminMemberDao.adminAuthMgrDelete(idArr[i]);
			}
		} else {
			deleteCnt += this.adminMemberDao.adminMemberDelete(id);
			this.adminMemberDao.adminAuthMgrDelete(id);
		}
		return deleteCnt;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.omp.admin.adminmgr.auth.service.AdminMemberService#adminMemberCreate(com.omp.admin.adminmgr.auth.model.
	 * AdminMember)
	 */
	@Override
	public AdminMember adminMemberCreate(AdminMember adminMem) {
		return this.adminMemberDao.adminMemberCreate(adminMem);

	}

	@Override
	public AdminMember adminMemberFind(String id) {
		return this.adminMemberDao.adminMemberFind(id);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.omp.admin.adminmgr.auth.service.AdminMemberService#adminMemberList()
	 */
	@Override
	public PageResultList adminMemberList(PageNavigator pageNavi, AdminMember adminMem) {

		return this.adminMemberDao.adminMemberList(pageNavi, adminMem);
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @deprecated
	 */
	@Deprecated
	@Override
	public List adminAuthMgrList(String mgrId) {

		return this.adminMemberDao.adminAuthMgrList(mgrId);
	}

	private Iterator<String> parseCheckMenuId(String menuId) {

		String[] mgrIdStrings = menuId.split(",");

		HashSet<String> set = new HashSet<String>();
		for (int i = 0; i < mgrIdStrings.length; i++) {
			String tmpStr = mgrIdStrings[i];
			if (tmpStr.length() == 10) {
				String dep1Str = tmpStr.substring(0, 4);
				String dep2Str = tmpStr.substring(0, 7);
				String dep3str = tmpStr.substring(0, 10);
				set.add(dep1Str);
				set.add(dep2Str);
				set.add(dep3str);
			}
		}

		Iterator<String> it = set.iterator();
		return it;

	}

	@Override
	public int adminAuthMgrUpdate(String mgrIdArr, String menuIdArr, String loginId) throws Exception {
		String[] mgrIdStrings = mgrIdArr.split(",");
		String[] menuIdStrings = menuIdArr.split(",");
		int returnCnt = 0;
		try {

			OmpLogger.debug("##mgrIdStrings=" + mgrIdStrings.toString());
			OmpLogger.debug("##menuIdStrings=" + menuIdStrings.toString());

			this.daoManager.startTransaction();

			for (int i = 0; i < mgrIdStrings.length; i++) {

				OmpLogger.debug("##mgrIdStrings[i]=" + mgrIdStrings[i]);

				// 해당 계정의 권한을 전부 삭제한다.
				this.adminMemberDao.adminAuthMgrDelete(mgrIdStrings[i]);

				Iterator<String> it = this.parseCheckMenuId(menuIdArr);

				returnCnt += this.adminMemberDao.adminAuthMgrInsert(mgrIdStrings[i], "ROOT", loginId);
				while (it.hasNext()) {

					String tmpMenuId = it.next();
					OmpLogger.debug("##mgrIdStrings[j]=" + mgrIdStrings[i]);
					OmpLogger.debug("##menuIdStrings[j]=" + tmpMenuId);

					// 해당 계정의 권한을 전부 insert 한다.
					returnCnt += this.adminMemberDao.adminAuthMgrInsert(mgrIdStrings[i], tmpMenuId, loginId);

				}
			}

			this.daoManager.commitTransaction();
		} catch (Exception e) {
			OmpLogger.error("", e);
			throw e;
		} finally {
			this.daoManager.endTransaction();
		}
		return returnCnt;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.omp.admin.adminmgr.auth.service.AdminMemberService#adminLogin(com.omp.admin.adminmgr.auth.model.AdminMember)
	 */
	@Override
	public AdminMember adminLogin(AdminMember adminMem) {
		AdminMember mem = this.adminMemberDao.adminLogin(adminMem);
		// adminMemberDao.adminMemberLoginDateUpdate(adminMem.getId()); //최종접속시간 업데이트 skip
		return mem;

	}

	/*
	 * 운영자 권한 부여 팝업 리스트
	 */
	@Override
	public HashMap<String, List> adminMemberMgrAll(String id) {

		HashMap<String, List> map = new HashMap<String, List>();
		List<AdminAuthMgr> depth1List = this.adminMemberDao.adminMemberMgrAll(id, "", "1");

		for (int p = 0; p < depth1List.size(); p++) { // 루트는 하나만 존재

			AdminAuthMgr auth1 = depth1List.get(p);
			String depth1Code = auth1.getMenuId(); // 루트 메뉴코드

			// 2depth menu list // 운영자관리
			List<AdminAuthMgr> depth2List = this.adminMemberDao.adminMemberMgrAll(id, depth1Code, "2");
			map.put(depth1Code, depth2List);

			for (int k = 0; k < depth2List.size(); k++) {

				AdminAuthMgr auth2 = depth2List.get(k);
				String depth2Code = auth2.getMenuId();
				List<AdminAuthMgr> depth3List = this.adminMemberDao.adminMemberMgrAll(id, depth2Code, "3");
				map.put(depth2Code, depth3List);

				for (int i = 0; i < depth3List.size(); i++) {
					AdminAuthMgr authMgr = depth3List.get(i);
					String depth3Code = authMgr.getMenuId();

					List<AdminAuthMgr> depth4List = this.adminMemberDao.adminMemberMgrAll(id, depth3Code, "4");

					map.put(depth3Code, depth4List);
				}

			}

		}

		return map; // adminMemberDao.adminAuthLeftMenuList(id, topCode, menuDepth);
	}

	/*
	 * 로그인시 세션에 권한 정보를 가지고 있기 위한 맵 (non-Javadoc)
	 * 
	 * @see com.omp.admin.adminmgr.auth.service.AdminMemberService#adminAuthLeftMenuList(java.lang.String,
	 * java.lang.String)
	 */
	@Override
	public HashMap<String, List> adminAuthLeftMenuListAllMap(String id) {

		HashMap<String, List> map = new HashMap<String, List>();

		OmpLogger.debug("ROOT 쿼리########");
		List<AdminAuthMgr> depth1List = this.adminMemberDao.adminAuthLeftMenuListMap(id, "", "1");
		OmpLogger.debug("ROOT 쿼리 결과########" + depth1List.size());
		if (depth1List.size() > 0) { // 루트는 하나만 존재

			AdminAuthMgr auth1 = depth1List.get(0);
			String depth1Code = auth1.getMenuId(); // 루트 메뉴코드

			// 2depth menu list // 운영자관리
			List<AdminAuthMgr> depth2List = this.adminMemberDao.adminAuthLeftMenuListMap(id, depth1Code, "2");
			map.put(depth1Code, depth2List);

			for (int k = 0; k < depth2List.size(); k++) {

				AdminAuthMgr auth2 = depth2List.get(k);
				String depth2Code = auth2.getMenuId();
				List<AdminAuthMgr> depth3List = this.adminMemberDao.adminAuthLeftMenuListMap(id, depth2Code, "3");
				map.put(depth2Code, depth3List);

				for (int i = 0; i < depth3List.size(); i++) {
					AdminAuthMgr authMgr = depth3List.get(i);
					String depth3Code = authMgr.getMenuId();

					List<AdminAuthMgr> depth4List = this.adminMemberDao.adminAuthLeftMenuListMap(id, depth3Code, "4");

					map.put(depth3Code, depth4List);
				}

			}
		}

		return map; // adminMemberDao.adminAuthLeftMenuList(id, topCode, menuDepth);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.omp.admin.adminmgr.auth.service.AdminMemberService#adminAuthTopMenuList(java.lang.String)
	 */
	@Override
	public List adminAuthTopMenuList(String id) {

		return this.adminMemberDao.adminAuthTopMenuList(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.omp.admin.adminmgr.auth.service.AdminMemberService#adminMemberUpdate(com.omp.admin.adminmgr.auth.model.
	 * AdminMember)
	 */
	@Override
	public int adminMemberUpdate(AdminMember adminMem) {

		return this.adminMemberDao.adminMemberUpdate(adminMem);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.omp.admin.adminmgr.auth.service.AdminMemberService#isAdminValidPageAuth(java.util.HashMap)
	 */
	@Override
	public boolean isAdminValidPageAuth(String mgrId, String menuId) {

		HashMap map = new HashMap();
		map.put("mgrId", mgrId);
		map.put("menuId", menuId);
		return this.adminMemberDao.isAdminValidPageAuth(map);
	}

	/**
	 * 로그인 정보 저장
	 */
	@Override
	public String insertLoginInfo(String mbrId, String accIp, String accDttm) {
		String loginSeq = "";
		try {
			// 트랜잭션 시작
			this.daoManager.startTransaction();

			loginSeq = this.adminMemberDao.getInsertLoginInfoSeq();
			OmpLogger.info("insertLoginInfo loginSeq =" + loginSeq);
			this.adminMemberDao.insertLoginInfo(loginSeq, mbrId, accIp, accDttm);
			this.daoManager.commitTransaction();
		} catch (Exception e) {
			OmpLogger.error("", e);
			// throw e;
		} finally {
			this.daoManager.endTransaction();
		}
		return loginSeq;
	}

	/**
	 * 고객정보조회 로그 저장
	 */
	@Override
	public void insertIDMSCusInfoLog(HashMap map) {
		try {
			this.adminMemberDao.insertIDMSCusInfoLog(map);
		} catch (Exception e) {
			OmpLogger.error("", e);
			// throw e;
		} finally {
		}
	}

	/**
	 * 관리자 비밀번호 동일 여부 카운트.
	 */
	@Override
	public int getConfirmCountByPassword(HashMap<String, String> map) {
		return this.adminMemberDao.getConfirmCountByPassword(map);
	}

	/**
	 * 관리자 비밀번호 변경
	 */
	@Override
	public void updateAdminPassword(HashMap<String, String> map) {

		try {
			this.daoManager.startTransaction(); // Transaction
			this.adminMemberDao.updateAdminPassword(map);
			this.daoManager.commitTransaction();
		} catch (Exception e) {
			OmpLogger.error("", e);
		} finally {
			this.daoManager.endTransaction();
		}
	}

	/**
	 * 비밀번호 변경 대상 관리자 정보 취득
	 */
	@Override
	public List<AdminMember> getUpdateAdminInfo() {
		return this.adminMemberDao.getUpdateAdminInfo();
	}

	/**
	 * 회원 리스트를 조회한다.
	 * 
	 * @param map
	 * @return
	 */
	@Override
	public List<HashMap<String, String>> getMemberList(HashMap<String, String> param) {
		return this.adminMemberDao.getMemberList(param);
	}

	/**
	 * 회원 LogOut 일시를 update한다.
	 * 
	 * @param map
	 * @return
	 */
	@Override
	public void updateLogoutInfo(HashMap<String, String> map) {

		try {
			this.adminMemberDao.updateLogoutInfo(map);
		} catch (Exception e) {
			OmpLogger.error("", e);
		} finally {
		}
	}

	/**
	 * <pre>
	 * admin id 계정이 상용 IDMS에 있는지 연동
	 * </pre>
	 * 
	 * @param loginId
	 * @return
	 */
	@Override
	public HashMap<String, String> linkIDMS(String loginId, String clntIp) {
		HashMap<String, String> idmsResultMap = new HashMap();
		String logPrefixString = "IDMS | " + loginId + " | ";
		OmpLogger.info(logPrefixString + "adminLoginIDMS..BEGIN=========");
		HttpsURLConnection conn = null;
		BufferedReader rd = null;
		StringBuilder sb = null;
		String line = null;
		int timeOut = 6000;
		StringBuffer logSB = new StringBuffer();

		try {
			DevProperties prop = new DevProperties();
			String idmsIp = prop.getString("omp.admin.auth.idms.ip");
			logSB.append("\n idmsIp(omp.admin.auth.idms.ip) | " + idmsIp);
			logSB.append("\n clntIp | " + clntIp);

			String idmsUrl = "https://" + idmsIp + "/CrtfcUsr.do?sysId=TSADM&clntIp=" + clntIp + "&loginId=" + loginId;// StringUtil.getLocalServerIp()
			logSB.append("\n idmsUrl | " + idmsUrl);

			// URLConnection conn = url.openConnection();
			conn = (HttpsURLConnection) new URL(idmsUrl).openConnection();
			conn.setHostnameVerifier(new CustomizedHostnameVerifier());

			conn.setConnectTimeout(timeOut);
			conn.setReadTimeout(timeOut);

			rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), "euc-kr"));
			sb = new StringBuilder();

			while ((line = rd.readLine()) != null) {
				sb.append(line + '\n');
			}
			logSB.append("\n sbResponse | " + sb);

			JsonParser parser = new JsonParser();
			JsonElement element = parser.parse(sb.toString());
			JsonObject json = element.getAsJsonObject();

			// JsonObject에서 문자열을 추출 {"RESULT_CD":"E0","RESULT_MSG":"성공"}
			String result_cd = (json.get("RESULT_CD") != null ? json.get("RESULT_CD").toString() : "");
			String result_msg = (json.get("RESULT_MSG") != null ? json.get("RESULT_MSG").toString() : "");

			// json object에는 시작과 끝에 "문자가 붙어서 리턴되기때문에 "문자 제거
			if (result_cd != null)
				result_cd = result_cd.replaceAll("\"", "");
			if (result_msg != null) {
				result_msg = result_msg.replaceAll("\"", "");
				result_msg = result_msg.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
			}
			idmsResultMap.put("result_cd", result_cd);
			idmsResultMap.put("result_msg", result_msg);

			logSB.append("\n json.get(RESULT_CD) | " + result_cd);
			logSB.append("\n json.get(RESULT_MSG) | " + result_msg);

		} catch (SocketTimeoutException ste) {
			OmpLogger.error(logPrefixString + ste.getMessage(), ste);
			logSB.append("\n SocketTimeoutException | " + ste.getMessage());
			idmsResultMap.put("result_cd", "E0");// IDMS 오류인경우 IDMS연동 정상처리
		} catch (Exception e) {
			logSB.append("\n Exception | " + e.getMessage());
			OmpLogger.error(logPrefixString + e.getMessage(), e);
			idmsResultMap.put("result_cd", "E0");// IDMS 오류인경우 IDMS연동 정상처리
		} finally {
			conn.disconnect();
			rd = null;
			sb = null;
			conn = null;
		}
		idmsResultMap.put("logSB", logSB.toString());
		return idmsResultMap;
	}

	private static class CustomizedHostnameVerifier implements HostnameVerifier {
		@Override
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}
}
